// Package sys
// @Link  https://github.com/bufanyun/hotgo
// @Copyright  Copyright (c) 2024 HotGo CLI
// @Author  Ms <133814250@qq.com>
// @License  https://github.com/bufanyun/hotgo/blob/master/LICENSE
// @AutoGenerate Version 2.13.1
package sys

import (
	"context"
	"fmt"
	"hotgo/api/admin/stockblock"
	"hotgo/internal/model/input/sysin"
	"hotgo/internal/service"
	"hotgo/utility/tradeDate"
	"slices"
	"time"
)

var (
	StockBlock = cStockBlock{}
)

type cStockBlock struct{}

// List 查看板块轮动列表
func (c *cStockBlock) List(ctx context.Context, req *stockblock.ListReq) (res *stockblock.ListRes, err error) {
	// 最近八个工作日
	req.StockBlockListInp.Date = tradeDate.GetLatestDay()
	list, _, err := service.SysStockBlock().List(ctx, &req.StockBlockListInp)
	if err != nil {
		return
	}

	if list == nil {
		list = []*sysin.StockBlockListModel{}
	}
	var items []*stockblock.ListResItem
	var itemMaps = make(map[string][]*sysin.StockBlockListModel)
	for _, model := range list {
		itemMaps[model.Date] = append(itemMaps[model.Date], model)
	}
	for date, models := range itemMaps {
		items = append(items, &stockblock.ListResItem{
			Date: date,
			List: models,
		})
	}
	var nameBlock = make(map[string]*sysin.StockBlockListModel)
	for _, item := range items {
		models := item.List
		for _, model := range models {
			if _, ok := nameBlock[model.Name]; ok {
				nameBlock[model.Name].Strength += model.Strength
			} else {
				nameBlock[model.Name] = &sysin.StockBlockListModel{
					Code:     model.Code,
					Name:     model.Name,
					Strength: model.Strength,
				}
			}
		}
	}
	var static []*sysin.StockBlockListModel
	for _, model := range nameBlock {
		static = append(static, model)
	}
	slices.SortFunc(static, func(a, b *sysin.StockBlockListModel) int {
		return int(b.Strength - a.Strength)
	})
	slices.SortFunc(items, func(a, b *stockblock.ListResItem) int {
		aParse, _ := time.Parse(time.DateOnly, a.Date)
		bParse, _ := time.Parse(time.DateOnly, b.Date)
		return int(bParse.Unix() - aParse.Unix())
	})
	if len(static) > 10 {
		static = static[:10]
	}
	var platIds []string
	for i, item := range items {
		if len(item.List) > 10 {
			items[i].List = item.List[:10]
		}
		for _, model := range items[i].List {
			if !slices.Contains(platIds, model.Code) {
				platIds = append(platIds, model.Code)
			}
		}
	}
	var detailIn = new(sysin.StockBlockDetailListInp)
	detailIn.PlatIds = platIds
	detailItems, _, err := service.SysStockBlockDetail().List(ctx, detailIn)
	var dateDetailMap = make(map[string][]*sysin.StockBlockDetailListModel)
	var dateDetailCodeMap = make(map[string][]string)
	for _, detailItem := range detailItems {
		detailKey := fmt.Sprintf("%s-%s", detailItem.Date, detailItem.BlockCode)
		if !slices.Contains(dateDetailCodeMap[detailKey], detailItem.Code) {
			dateDetailMap[detailKey] = append(dateDetailMap[detailKey], detailItem)
			dateDetailCodeMap[detailKey] = append(dateDetailCodeMap[detailKey], detailItem.Code)
		}
	}
	for _, item := range items {
		date := item.Date
		item.DetailItems = make(map[string][]*sysin.StockBlockDetailListModel)
		for _, model := range item.List {
			detailKey := fmt.Sprintf("%s-%s", date, model.Code)
			name := model.Name
			item.DetailItems[name] = dateDetailMap[detailKey]
			slices.SortFunc(item.DetailItems[name], func(a, b *sysin.StockBlockDetailListModel) int {
				aPosition := a.Position
				bPosition := b.Position
				var aScore = float64(0)
				var bScore = float64(0)
				position := map[string]float64{
					"龙一":  1000,
					"龙二":  990,
					"龙三":  980,
					"龙四":  970,
					"龙五":  960,
					"龙六":  950,
					"龙七":  940,
					"龙八":  930,
					"龙九":  920,
					"龙十":  910,
					"龙十一": 900,
					"龙十二": 890,
					"龙十三": 880,
				}
				aScore, _ = position[aPosition]
				bScore, _ = position[bPosition]
				if aScore == 0 {
					aScore = a.ChangePercent * 10
				}
				if bScore == 0 {
					bScore = b.ChangePercent * 10
				}

				return int(bScore - aScore)
			})
		}
	}
	res = new(stockblock.ListRes)
	res.Items = items
	res.Static = static
	return
}

// Export 导出板块轮动列表
func (c *cStockBlock) Export(ctx context.Context, req *stockblock.ExportReq) (res *stockblock.ExportRes, err error) {
	err = service.SysStockBlock().Export(ctx, &req.StockBlockListInp)
	return
}

// Edit 更新板块轮动
func (c *cStockBlock) Edit(ctx context.Context, req *stockblock.EditReq) (res *stockblock.EditRes, err error) {
	err = service.SysStockBlock().Edit(ctx, &req.StockBlockEditInp)
	return
}

// View 获取指定板块轮动信息
func (c *cStockBlock) View(ctx context.Context, req *stockblock.ViewReq) (res *stockblock.ViewRes, err error) {
	data, err := service.SysStockBlock().View(ctx, &req.StockBlockViewInp)
	if err != nil {
		return
	}

	res = new(stockblock.ViewRes)
	res.StockBlockViewModel = data
	return
}

// Delete 删除板块轮动
func (c *cStockBlock) Delete(ctx context.Context, req *stockblock.DeleteReq) (res *stockblock.DeleteRes, err error) {
	err = service.SysStockBlock().Delete(ctx, &req.StockBlockDeleteInp)
	return
}
